﻿using DotNetExtensions.Core.Restful;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace DotNetExtensions.Core.Http
{
    public static class HttpResponseExtensions
    {
        /// <summary>
        /// 将返回数据强制转换成ApiResult<T>格式
        /// 注意：
        /// 1、此方法不会判断是否为RestfulHttpRequest类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="response"></param>
        /// <returns></returns>
        public static ApiResult<T> To<T>(this HttpResponse response)
        {
            ApiResult<T> apiResult = new ApiResult<T>(response.Code, string.Empty, default(T));

            if (response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                return JsonConvert.DeserializeObject<ApiResult<T>>(data);
            }
            else if (!response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                apiResult.Msg = data;
            }

            return apiResult;
        }

        public static bool TryTo<T>(this HttpResponse response, out ApiResult<T> apiResult)
        {
            apiResult = new ApiResult<T>(response.Code, string.Empty, default(T));

            if (response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                apiResult = JsonConvert.DeserializeObject<ApiResult<T>>(data);

                return apiResult != null;
            }
            else if (!response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                apiResult.Msg = data;
            }

            return false;
        }

        public static T Parse<T>(this HttpResponse response) where T : class, new()
        {
            try
            {
                if (response.OK && response.Content != null && response.Content.Length > 0)
                {
                    string data = Encoding.UTF8.GetString(response.Content);
                    return JsonConvert.DeserializeObject<T>(data);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error:{0}", ex.Message);
            }
            return null;
        }
        public static bool TryParse<T>(this HttpResponse response, out T value) where T : class, new()
        {
            value = default(T);
            try
            {
                if (response.OK && response.Content != null && response.Content.Length > 0)
                {
                    string data = Encoding.UTF8.GetString(response.Content);
                    value = JsonConvert.DeserializeObject<T>(data);

                    return value != null;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error:{0}", ex.Message);
            }
            return false;
        }

        /// <summary>
        /// 将返回数据强制转换成ApiResult<T>格式
        /// 注意：
        /// 1、此方法不会判断是否为RestfulHttpRequest类型
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        public static ApiResult To(this HttpResponse response)
        {
            ApiResult apiResult = new ApiResult(response.Code, string.Empty, null);

            if (response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                return JsonConvert.DeserializeObject<ApiResult>(data);
            }
            else if (!response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                apiResult.Msg = data;
            }

            return apiResult;
        }
        public static bool TryTo(this HttpResponse response, out ApiResult apiResult)
        {
            apiResult = new ApiResult(response.Code, string.Empty, null);

            if (response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                apiResult = JsonConvert.DeserializeObject<ApiResult>(data);

                return apiResult != null;
            }
            else if (!response.OK && response.Content != null && response.Content.Length > 0)
            {
                string data = Encoding.UTF8.GetString(response.Content);
                apiResult.Msg = data;
            }

            return false;
        }

        /// <summary>
        /// 将返回数据保存为文件
        /// 注意：
        /// 1、此方法不会判断是否为FileHttpRequest类型
        /// 2、目标文件如果存在会覆盖
        /// </summary>
        /// <param name="response"></param>
        /// <param name="filename">文件绝对路径（确保路径合法）</param>
        /// <returns></returns>
        public static bool Save(this HttpResponse response, string filename)
        {
            if (response.OK && response.Content != null && response.Content.Length > 0)
            {
                try
                {
                    string dir = Path.GetDirectoryName(filename);
                    if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);

                    using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
                    {
                        int bufferLen = 1024 * 4;
                        int total = response.Content.Length;

                        int length = (total - 1) / bufferLen + 1;
                        for (int i = 0; i < length; i++)
                        {
                            var buffer = response.Content.Skip(bufferLen * i).Take(bufferLen).ToArray();

                            fs.Write(buffer, 0, buffer.Length);
                            fs.Flush();
                        }
                    }

                    return true;
                }
                catch
                {
                    return false;
                }
            }

            return false;
        }

        public static string GetString(this HttpResponse response, Encoding encoding = null)
        {
            if (response.Content != null && response.Content.Length > 0)
            {
                if (encoding == null) encoding = Encoding.UTF8;
                return encoding.GetString(response.Content);
            }

            return null;
        }
        public static string ToString(this HttpResponse response, Encoding encoding = null)
        {
            if (response.Content != null && response.Content.Length > 0)
            {
                if (encoding == null) encoding = Encoding.UTF8;
                return encoding.GetString(response.Content);
            }

            return null;
        }
    }
}
